<!DOCTYPE html>
<html lang="zh-cn">

    <head>
        <meta charset="UTF-8">
        <title class="title">[文件管理器]</title>
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <style type="text/css">
            .content {
                background: transparent;
            }

            .btn {
                position: relative;
                top: 0;
                left: 0;
                bottom: 0;
                right: 0;
            }

            .btn .file {
                position: fixed;
                z-index: 93;
                left: 0;
                right: 0;
                top: 0;
                bottom: 0;
                width: 100%;
                opacity: 0;
            }
        </style>
    </head>

    <body>

        <div id="content" class="content">
            <div class="btn">
                <input :multiple="multiple" @change="onChange" :accept="accept" ref="file" class="file" type="file" />
            </div>
        </div>

        <script type="text/javascript" src="js/vue.min.js"></script>
        <script type="text/javascript">
            let _this;
            var vm = new Vue({
                el: '#content',
                data: {
                    accept: '',
                    multiple: true,
                },
                mounted() {
                    this.debug && console.log('加载webview');
                    _this = this;
                    this.files = new Map();
                    document.addEventListener('plusready', (e) => {
                        let { debug, instantly, prohibited } = plus.webview.currentWebview();
                        this.debug = debug;
                        this.instantly = instantly;
                        this.prohibited = prohibited;
                        this.accept = prohibited.accept;
                        this.multiple = prohibited.count > 1;
                        location.href = 'callback?retype=updateOption';
                    }, false);
                },
                methods: {
                    toast(msg) {
                        plus.nativeUI.toast(msg);
                    },
                    clear(name) {
                        if (!name) {
                            this.files.clear();
                            return;
                        }
                        this.files.delete(name);
                    },
                    setData(option = '{}') {
                        this.debug && console.log('更新参数：' + option);
                        try {
                            _this.option = JSON.parse(option);
                        } catch (e) {
                            console.error('参数设置错误')
                        }
                    },
                    async upload(name = '') {
                        if (name && this.files.has(name)) {
                            await this.createUpload(this.files.get(name));
                        }
                        else {
                            for (let item of this.files.values()) {
                                if (item.type === 'waiting' || item.type === 'fail') {
                                    await this.createUpload(item);
                                }
                            }
                        }
                    },
                    onChange(e) {
                        let fileDom = this.$refs.file;
                        for (let file of fileDom.files) {
                            if (this.files.size >= this.prohibited.count) {
                                this.toast(`只允许上传${this.prohibited.count}个文件`);
                                fileDom.value = '';
                                break;
                            }
                            this.addFile(file);
                        }
                        this.uploadAfter();
                        fileDom.value = '';
                    },
                    addFile(file) {
                        if (file) {
                            let name = file.name;
                            this.debug && console.log('文件名称', name, '大小', file.size);
                            // 限制文件格式
                            let suffix = name.substring(name.lastIndexOf(".") + 1).toLowerCase();
                            let formats = this.prohibited.formats.toLowerCase();
                            if (formats && !formats.includes(suffix)) {
                                this.toast(`不支持上传${suffix.toUpperCase()}格式文件`);
                                return;
                            }
                            // 限制文件大小
                            if (file.size > 1024 * 1024 * Math.abs(this.prohibited.size)) {
                                this.toast(`附件大小请勿超过${this.prohibited.size}M`)
                                return;
                            }
                            let path = URL.createObjectURL(file);
                            this.files.set(file.name, { file, path, name: file.name, size: file.size, progress: 0, type: 'waiting' });
                        }
                    },
                    /**
                     * @returns {Map} 已选择的文件Map集
                     */
                    callChange() {
                        location.href = 'callback?retype=change&files=' + escape(JSON.stringify([...this.files]));
                    },
                    /**
                     * @returns {object} 正在处理的当前对象
                     */
                    changeFilesItem(item, end = '') {
                        this.files.set(item.name, item);
                        location.href = 'callback?retype=progress&end=' + end + '&item=' + escape(JSON.stringify(item));
                    },
                    uploadAfter() {
                        this.callChange();
                        this.instantly && this.upload();
                    },
                    createUpload(item) {
                        this.debug && console.log('准备上传,option=：' + JSON.stringify(this.option));
                        item.type = 'loading';
                        delete item.responseText;
                        return new Promise((resolve, reject) => {
                            let { url, name, method = 'POST', header = {}, formData = {} } = this.option;
                            let form = new FormData();
                            for (let keys in formData) {
                                form.append(keys, formData[keys])
                            }
                            form.append(name, item.file);

                            //xcg：根据选择的文件，生成文件名，给七牛用的
                            let key = this.GenerateFileName(item.file)
                            form.append("key", key);

                            let xmlRequest = new XMLHttpRequest();
                            xmlRequest.open(method, url, true);
                            for (let keys in header) {
                                xmlRequest.setRequestHeader(keys, header[keys])
                            }
                            xmlRequest.upload.addEventListener('progress', event => {
                                if (event.lengthComputable) {
                                    let progress = Math.ceil((event.loaded * 100) / event.total)
                                    if (progress <= 100) {
                                        item.progress = progress;
                                        this.changeFilesItem(item);
                                    }
                                }
                            }, false);

                            xmlRequest.ontimeout = () => {
                                console.error('请求超时')
                                item.type = 'fail';
                                this.changeFilesItem(item, true);
                                return resolve(false);
                            }

                            xmlRequest.onreadystatechange = ev => {
                                if (xmlRequest.readyState == 4) {
                                    if (xmlRequest.status == 200) {
                                        this.debug && console.log('上传完成：' + xmlRequest.responseText)
                                        item['responseText'] = xmlRequest.responseText;
                                        item.type = 'success';
                                        this.changeFilesItem(item, true);
                                        return resolve(true);
                                    } else if (xmlRequest.status == 0) {
                                        console.error('status = 0 :请检查请求头Content-Type与服务端是否匹配，服务端已正确开启跨域，并且nginx未拦截阻止请求')
                                    }
                                    console.error('--ERROR--：status = ' + xmlRequest.status)
                                    item.type = 'fail';
                                    this.changeFilesItem(item, true);
                                    return resolve(false);
                                }
                            }
                            xmlRequest.send(form)
                        });

                    },

                    //xcg，添加方法
                    GenerateFileName(file) {
                        let fileInfo = this.GetUrlFileName(file.name);
                        return fileInfo.fileName + "-" + new Date().getTime() + "." + fileInfo.extName;
                    },

                    //xcg，添加方法
                    GetUrlFileName(url) {
                        let res = {
                            fileName: url.substring(url.lastIndexOf("/") + 1, url.lastIndexOf(".")),
                            extName: url.substring(url.lastIndexOf(".") + 1),
                            fullName: url.substring(url.lastIndexOf("/") + 1)
                        };
                        return res;
                    }
                }
            });

        </script>
    </body>

</html>